package com.yzycoc.hamster.demo.time202507.image;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.Set;

/**
 * 上传图片
 */
public class ImmediateSaveImageUploader {
    // 配置项
    private static final String API_BASE_URL = "https://img.lolimi.cn/api/v1";
    private static final String EMAIL = "936642284@qq.com";
    private static final String PASSWORD = "yaozhenyong0.";
    private static final String RECORD_JSON_PATH = "image/upload_records.json";
    private static final String SQL_OUTPUT_PATH = "image/upload_records.sql";
    private static final String FOLDER_TO_UPLOAD = "E:\\system\\Pictures\\ys2";

    public static void main(String[] args) {
        try {
            // 1. 初始化系统
            initializeSystem();

            // 2. 认证获取Token
            String authToken = authenticate();
            if (authToken == null) {
                System.exit(1);
            }

            // 3. 处理图片文件
            processImages(authToken);

            System.out.println("=== 所有文件处理完成 ===");
        } catch (Exception e) {
            System.err.println("程序执行出错: " + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
    }

    /**
     * 初始化系统
     */
    private static void initializeSystem() throws Exception {
        System.out.println("=== 初始化系统 ===");

        // 创建必要目录
        FileUtil.mkdir(FileUtil.file(RECORD_JSON_PATH).getParent());
        FileUtil.mkdir(FileUtil.file(SQL_OUTPUT_PATH).getParent());
        System.out.println(new File(RECORD_JSON_PATH).getAbsolutePath());
        // 初始化空记录文件
        if (!FileUtil.exist(RECORD_JSON_PATH)) {
            FileUtil.writeString("[]", RECORD_JSON_PATH, StandardCharsets.UTF_8);
        }

        if (!FileUtil.exist(SQL_OUTPUT_PATH)) {
            FileUtil.writeString("", SQL_OUTPUT_PATH, StandardCharsets.UTF_8);
        }

        // 检查上传目录
        if (!FileUtil.exist(FOLDER_TO_UPLOAD)) {
            throw new Exception("上传目录不存在: " + FOLDER_TO_UPLOAD);
        }
    }

    /**
     * 认证获取Token
     */
    private static String authenticate() throws Exception {
        System.out.println("=== 认证获取Token ===");

        JSONObject authData = new JSONObject();
        authData.put("email", EMAIL);
        authData.put("password", PASSWORD);

        HttpResponse response = HttpRequest.post(API_BASE_URL + "/tokens")
                .body(authData.toJSONString())
                .execute();

        if (!response.isOk()) {
            throw new Exception("认证失败，状态码: " + response.getStatus());
        }

        JSONObject result = JSON.parseObject(response.body());
        if (!result.getBooleanValue("status")) {
            throw new Exception("认证失败: " + result.getString("message"));
        }

        return result.getJSONObject("data").getString("token");
    }

    /**
     * 处理图片文件
     */
    private static void processImages(String authToken) throws Exception {
        System.out.println("=== 开始处理图片 ===");

        // 加载历史记录
        Set<String> uploadedFiles = loadUploadedFiles();

        File[] files = FileUtil.ls(FOLDER_TO_UPLOAD);
        if (files == null || files.length == 0) {
            System.out.println("没有找到可处理的图片文件");
            return;
        }

        int total = files.length;
        int processed = 0;

        for (File file : files) {
            if (!file.isFile()) continue;

            String filePath = file.getAbsolutePath();
            String fileName = file.getName();
            String extension = FileNameUtil.extName(fileName).toLowerCase();

            // 检查文件类型
            if (!isValidImage(extension)) {
                System.out.println("跳过非图片文件: " + fileName);
                continue;
            }

            // 检查是否已上传
            if (uploadedFiles.contains(filePath)) {
                System.out.println("跳过已上传文件: " + fileName);
                continue;
            }

            // 处理单个文件
            boolean success = processSingleFile(file, authToken);
            if (success) {
                processed++;
            }

            System.out.printf("进度: %d/%d (%.1f%%)%n",
                    processed, total, (processed * 100.0 / total));
        }
    }

    /**
     * 处理单个文件
     */
    private static boolean processSingleFile(File file, String authToken) {
        String filePath = file.getAbsolutePath();
        String fileName = file.getName();

        try {
            // 获取图片信息
            long fileSize = file.length();
            int[] dimensions = getImageDimensions(file);

            // 上传图片
            JSONObject uploadResult = uploadFile(file, authToken);
            if (uploadResult == null || !uploadResult.getBooleanValue("status")) {
                throw new Exception("上传失败: " +
                        (uploadResult != null ? uploadResult.getString("message") : "未知错误"));
            }

            // 获取URL
            String url = uploadResult.getJSONObject("data")
                    .getJSONObject("links")
                    .getString("url");
            if (StrUtil.isBlank(url)) {
                throw new Exception("获取URL失败");
            }

            // 创建记录
            JSONObject record = new JSONObject();
            record.put("filePath", filePath);
            record.put("fileName", fileName);
            record.put("fileSize", fileSize);
            record.put("width", dimensions[0]);
            record.put("height", dimensions[1]);
            record.put("uploadTime", System.currentTimeMillis());
            record.put("response", uploadResult);

            // 立即保存记录
            saveRecord(record);

            System.out.println("上传成功: " + fileName);
            return true;
        } catch (Exception e) {
            System.err.println("处理文件失败 [" + fileName + "]: " + e.getMessage());
            return false;
        }
    }

    /**
     * 上传文件
     */
    private static JSONObject uploadFile(File file, String authToken) {
        try {
            HttpResponse response = HttpRequest.post(API_BASE_URL + "/upload")
                    .header("Authorization", "Bearer " + authToken)
                    .form("file", file)
                    .execute();

            if (!response.isOk()) {
                System.err.println("上传失败，状态码: " + response.getStatus());
                return null;
            }

            return JSON.parseObject(response.body());
        } catch (Exception e) {
            System.err.println("上传过程中发生异常: " + e.getMessage());
            return null;
        }
    }

    /**
     * 保存记录
     */
    private static synchronized void saveRecord(JSONObject newRecord) throws Exception {
        // 加载现有JSON记录
        JSONArray records = JSON.parseArray(FileUtil.readString(RECORD_JSON_PATH, StandardCharsets.UTF_8));

        // 添加新记录
        records.add(newRecord);

        // 保存JSON文件
        FileUtil.writeString(JSON.toJSONString(records), RECORD_JSON_PATH, StandardCharsets.UTF_8);
        FileUtil.writeString(JSON.toJSONString(records), RECORD_JSON_PATH, StandardCharsets.UTF_8);

        // 生成并追加SQL
        String sql = generateSQL(newRecord);
        FileUtil.appendString(sql, SQL_OUTPUT_PATH, StandardCharsets.UTF_8);
    }

    /**
     * 生成SQL语句
     */
    private static String generateSQL(JSONObject record) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = LocalDateTime.now().format(dtf);

        String fileName = record.getString("fileName");
        String url = record.getJSONObject("response")
                .getJSONObject("data")
                .getJSONObject("links")
                .getString("url");
        int height = record.getIntValue("height");
        int width = record.getIntValue("width");
        long fileSizeKB = record.getLongValue("fileSize") / 1024;

        return String.format(
                "INSERT INTO `background`(`create_date`, `create_name`, `url`, `pc`, `is_user`, `height`, `width`, `types`, `user`, `remark`) " +
                        "VALUES ('%s', '%s', '%s', 1, b'1', %d, %d, '20', '%dKB', NULL);\n",
                currentTime,
                escapeSql(fileName),
                escapeSql(url),
                height,
                width,
                fileSizeKB
        );
    }

    /**
     * 加载已上传文件列表
     */
    private static Set<String> loadUploadedFiles() {
        Set<String> uploadedFiles = new HashSet<>();
        if (FileUtil.exist(RECORD_JSON_PATH)) {
            System.out.println(new File(RECORD_JSON_PATH).getAbsolutePath());
            JSONArray records = JSON.parseArray(FileUtil.readString(RECORD_JSON_PATH, StandardCharsets.UTF_8));
            records.forEach(obj -> {
                JSONObject record = (JSONObject) obj;
                uploadedFiles.add(record.getString("filePath"));
            });
        }

        return uploadedFiles;
    }

    /**
     * 获取图片尺寸
     */
    private static int[] getImageDimensions(File file) {
        try {
            BufferedImage image = ImageIO.read(file);
            return image != null ? new int[]{image.getWidth(), image.getHeight()} : new int[]{0, 0};
        } catch (Exception e) {
            System.err.println("获取图片尺寸失败: " + file.getName());
            return new int[]{0, 0};
        }
    }

    /**
     * 检查是否为有效图片
     */
    private static boolean isValidImage(String extension) {
        return StrUtil.equalsAnyIgnoreCase(extension,
                "jpg", "jpeg", "png", "gif", "bmp", "webp");
    }

    /**
     * SQL转义
     */
    private static String escapeSql(String str) {
        return str.replace("'", "''");
    }
}